﻿using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
using Ln.Audit.Domain.Repositories;
using Ln.Fram.Core.Helper;

namespace Ln.Audit.Domain;

public class AuditingStore : IAuditingStore, ITransientDependency
{
	public ILogger<AuditingStore> Logger { get; set; }
	protected IAuditLogRepository AuditLogRepository { get; }
	protected IUnitOfWorkManager UnitOfWorkManager { get; }
	protected AbpAuditingOptions Options { get; }
	protected IAuditLogInfoToAuditLogConverter Converter { get; }

	public AuditingStore(IAuditLogRepository auditLogRepository, IUnitOfWorkManager unitOfWorkManager, IOptions<AbpAuditingOptions> options, IAuditLogInfoToAuditLogConverter converter)
	{
		AuditLogRepository = auditLogRepository;
		UnitOfWorkManager = unitOfWorkManager;
		Converter = converter;
		Options = options.Value;
		Logger = NullLogger<AuditingStore>.Instance;
	}

	public virtual async Task SaveAsync(AuditLogInfo auditInfo)
	{
		if (!Options.HideErrors)
		{
			await SaveLogAsync(auditInfo);
			return;
		}
		try
		{
			await SaveLogAsync(auditInfo);
		}
		catch (Exception ex)
		{
			Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
			Logger.LogException(ex, LogLevel.Error);
		}
	}

	protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo)
	{
		Logger.LogDebug("Ln-请求追踪:" + JsonHelper.ObjToStr(auditInfo, "yyyy-MM-dd HH:mm:ss"));
		using (var uow = UnitOfWorkManager.Begin(true))
		{
			await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo));
			await uow.CompleteAsync();
		}
	}
}
